package com.hxexp.weixin.mvc.register.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.hxexp.weixin.common.exception.ServiceException;
import com.hxexp.weixin.constant.CacheName;
import com.hxexp.weixin.constant.CookieName;
import com.hxexp.weixin.constant.Errcode;
import com.hxexp.weixin.constant.Gender;
import com.hxexp.weixin.constant.IdentificationType;
import com.hxexp.weixin.constant.PassengerType;
import com.hxexp.weixin.constant.WebAppVersion;
import com.hxexp.weixin.hpe.api.login.model.LoginResultBean;
import com.hxexp.weixin.hpe.api.register.model.RegisterParamBean;
import com.hxexp.weixin.hpe.api.register.model.RegisterResultBean;
import com.hxexp.weixin.mvc.login.service.LoginService;
import com.hxexp.weixin.mvc.register.service.RegisterService;
import com.qq.weixin.constant.WebUserSex;
import com.qq.weixin.mp.api.oauth2.model.WebUserInfoBean;

/**
 * 用户注册controller
 * @author li.jiang
 *
 */
@Controller
@RequestMapping(value="/register")
public final class RegisterController {
    private static final Logger LOGGER = LoggerFactory.getLogger(RegisterController.class);
    @Autowired
    private RegisterService registerService;
    @Autowired
    private LoginService loginService;
    @Autowired
    private EhCacheCacheManager ehCacheManager;

    /**
     * 设置页面需要的常量
     *
     * @return
     */
    @ModelAttribute("constant")
    public Map<String, String> setConstant() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("IdentificationType_officercard", IdentificationType.OFFICERCARD); // 证件类别：军官证
        map.put("Errcode_Success", String.valueOf(Errcode.SUCCESS));
        map.put("Errcode_Fail", String.valueOf(Errcode.FAIL));

        return map;
    }
    /**
     * 注册用户并登录
     * @return
     */
    @RequestMapping(value="/add")
    public String addUser(RegisterParamBean registerParamBean, String returnUrl, Model model, HttpServletRequest request, HttpServletResponse response) {
        final String queryTicketUrl = request.getContextPath() + "/trafficline/index.do";

        try {
            RegisterResultBean registerResult = registerService.register(registerParamBean);
            LOGGER.debug("注册结果：{}", registerResult);
            String errmsg = ""; // 注册失败原因提示

            if (registerResult.getErrcode() == Errcode.SUCCESS) {

                // 注册成功后进行登录操作
                LoginResultBean loginResult = loginService.loginByUsername(registerParamBean.getUsername(), registerParamBean.getPassword());

                if (loginResult.getErrcode() == Errcode.SUCCESS) {
                    // 登录成功后记住登录用户，以便下次访问判断登录状态
                    loginService.rememberLoginUser(loginResult, response);
                    LOGGER.debug("用户：{} 已注册登录成功", registerParamBean.getUsername());

                    // 如果返回地址不存在，登录成功后重定向到查询页面；否则重定向到返回地址
                    if (StringUtils.isEmpty(returnUrl)) { // NOSONAR
                        try { // NOSONAR
                            response.sendRedirect(queryTicketUrl);
                        } catch (IOException e) {
                            LOGGER.error("请求重定向时发生IO异常!", e); // NOSONAR
                        }
                    } else {
                        LOGGER.debug("重定向地址：{}", returnUrl);
                        try { // NOSONAR
                            response.sendRedirect(returnUrl);
                        } catch (IOException e) {
                            LOGGER.error("请求重定向时发生IO异常!", e);
                        }
                    }
                } else {
                    errmsg = "登录时发生错误：" + Errcode.getMessage(loginResult.getErrcode());
                }
            } else {
                errmsg = "注册时发生错误：" + Errcode.getMessage(registerResult.getErrcode());
            }

            model.addAttribute("msg", errmsg);
        } catch (ServiceException e) { // NOSONAR
            model.addAttribute("msg", "服务器内部错误，注册失败！");
        }

        return "register_tips";
    }
    /**
     * 注册页面
     * @param returnUrl
     * @param model
     * @return
     */
    @RequestMapping(value="/index")
    public String index(String returnUrl, @CookieValue(value = CookieName.APP_VERSION, defaultValue = WebAppVersion.HX) String appVer, Model model) {
        LOGGER.debug("**********************返回链接地址：{}", returnUrl);
        model.addAttribute("returnUrl", returnUrl); // NOSONAR
        model.addAttribute("genderMap", Gender.CODE_NAME_MAP);
        model.addAttribute("identificationMap", IdentificationType.CODE_NAME_MAP);
        if (appVer.equals(WebAppVersion.NC)) {
            Map<String, String> passengerType = new HashMap<String, String>(1);
            passengerType.put(PassengerType.ADULT, "成人");
            model.addAttribute("passengerMap", passengerType); // NOSONAR
        } else {
            model.addAttribute("passengerMap", PassengerType.CODE_NAME_MAP);
        }

        return "register";
    }

    /**
     * 使用openid自动注册并登录
     *
     * @param returnUrl
     *            返回url地址
     * @param openid
     *            微信用户唯一标识
     * @param model
     * @return
     */
    @RequestMapping(value = "/autoadd")
    public String autoAddUser(String returnUrl, @CookieValue(value = CookieName.OPENID, defaultValue = "") String openid,
                              HttpServletResponse response, Model model) {
        if (!StringUtils.isEmpty(openid)) {
            Cache webUserInfoCache = ehCacheManager.getCache(CacheName.WEB_USERINFO);
            WebUserInfoBean userInfo = webUserInfoCache.get(openid, WebUserInfoBean.class);

            RegisterParamBean registerParam = new RegisterParamBean();
            registerParam.setOpenId(openid);
            if (userInfo != null && !userInfo.getSex().equals(WebUserSex.UNKNOWN)) {
                registerParam.setGender(userInfo.getSex());
            }

            try {
                RegisterResultBean registerResult = registerService.register(registerParam);
                if (registerResult.getErrcode() == Errcode.SUCCESS) {
                    LOGGER.debug("用户使用openid={} 注册成功", openid);

                    LoginResultBean loginResult = loginService.loginByOpenId(openid);
                    if (loginResult.getErrcode() == Errcode.SUCCESS) { // NOSONAR
                        loginService.rememberLoginUser(loginResult, response);
                        LOGGER.debug("用户使用openid={} 登录成功", openid);

                        model.addAttribute("msg", "注册登录成功");
                        model.addAttribute("errcode", String.valueOf(Errcode.SUCCESS)); // NOSONAR
                        model.addAttribute("returnUrl", returnUrl);
                    } else {
                        LOGGER.debug("用户使用openid={} 登录失败", openid);
                        model.addAttribute("msg", "登录失败");
                        model.addAttribute("errcode", String.valueOf(Errcode.FAIL));
                    }
                } else {
                    LOGGER.debug("用户使用openid={} 注册失败", openid);
                    model.addAttribute("msg", "注册失败");
                    model.addAttribute("errcode", String.valueOf(Errcode.FAIL));
                }

            } catch (ServiceException e) {
                LOGGER.error("注册时发生异常!", e);
                model.addAttribute("msg", "注册失败，服务器内部发生异常");
                model.addAttribute("errcode", String.valueOf(Errcode.FAIL));
            }

        } else {
            LOGGER.debug("微信用户openid未获取到，注册失败"); // NOSONAR
            model.addAttribute("msg", "微信用户openid未获取到，注册失败");
            model.addAttribute("errcode", String.valueOf(Errcode.FAIL));
        }

        return "autoregister_tips";
    }
}
